#include <algorithm>
#include <functional>
#include "timer.h"
#include "asynevent.h"


static void timeout_cb(evutil_socket_t fd, short event, void *user_data)
{
	(static_cast<NTDTimer *>(user_data))->OnTimer();
}


NTDTimer::NTDTimer()
{
	timeout_event_ = NULL;
}

NTDTimer::~NTDTimer()
{
	Stop();
}

void NTDTimer::Start(int32 ms, bool cycle)
{
	//We'd better del first
	//event_del(timeout_event_);
	Stop();

	int16 evtype = 0;
	if( cycle ){
		evtype = EV_PERSIST;
	}
	timeout_event_ = event_new(AsynEventFramework::Instance()->GetEventBase(), -1, evtype, timeout_cb, this);
	struct timeval tv;
	evutil_timerclear(&tv);
	tv.tv_sec = static_cast<long>(ms/1000);
	tv.tv_usec = static_cast<long>(1000 * ms - tv.tv_sec * 1000000);
	event_add(timeout_event_, &tv);
}

void NTDTimer::Stop()
{
	if(timeout_event_){
		event_del(timeout_event_);
		event_free(timeout_event_);
		timeout_event_ = NULL;
	}
}

void NTDTimer::OnTimer()
{
	std::for_each(listener_set_.begin(), listener_set_.end(), std::bind2nd(std::mem_fun1(&INTDTimerListener::OnTimer), this));
}

void NTDTimer::AddListener(INTDTimerListener * listener)
{
	listener_set_.insert(listener);
}

void NTDTimer::RemoveListener(INTDTimerListener * listener)
{
	listener_set_.erase(listener);
}